using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using Abp.Authorization;
using Abp.Authorization.Users;
using Abp.MultiTenancy;
using Abp.Runtime.Security;
using Abp.UI;
using Yozeev.Authentication.External;
using Yozeev.Authentication.JwtBearer;
using Yozeev.Authorization;
using Yozeev.Models.TokenAuth;
using Yozeev.MultiTenancy;
using Yozeev.UserManagerment.Users;
using Abp.Runtime.Caching;
using Yozeev.Authorization.Impersonation;
using Abp;
using Abp.Domain.Uow;
using Abp.IdentityFramework;
using Abp.Json;
using L._52ABP.Common.Consts;
using Yozeev.Authentication.External.ExternalAuth;
using Yozeev.Authentication.External.ExternalAuth.Dto;
using Yozeev.DataFileObjects;
using Yozeev.DataFileObjects.DataTempCache;
using Yozeev.Security.Captcha;
using Yozeev.UserManagerment.Users.UserLink;
using Abp.Extensions;
using L._52ABP.Common.Net.MimeTypes;
using L._52ABP.Core.VerificationCodeStore;
using Yozeev.BusinessLogic.DomainService;
using Yozeev.Models;
using Yozeev.BusinessLogic;
using Yozeev.EntityFrameworkCore;
using Yozeev.SystemConfig.BasicConfig.DomainService;
using Abp.Domain.Entities.Auditing;
using Yozeev.Help;

namespace Yozeev.Controllers
{
    [Route("api/[controller]/[action]")]
    public class AccountController : CommonController//YozeevControllerBase
    {
        private readonly ITenantCache _tenantCache;
        private readonly ICacheManager _cacheManager;
        private readonly IImpersonationManager _impersonationManager;
        private readonly IUserLinkManager _userLinkManager;
        private readonly IdentityOptions _identityOptions;
        private readonly IDataTempFileCacheManager _dataTempFileCacheManager;
        private readonly IDataFileObjectManager _dataFileObjectManager;
        private readonly AccountManager _accountManager;
        private readonly ActivityManager _activityManager;
        //private readonly SourceManager _sourceManager;


        public AccountController(
            ITenantCache tenantCache,
            ICacheManager cacheManager,
            IImpersonationManager impersonationManager,
            IUserLinkManager userLinkManager,
            IOptions<IdentityOptions> identityOptions,
            UserManager userManager, 
            IDataFileObjectManager dataFileObjectManager, 
            IDataTempFileCacheManager dataTempFileCacheManager
            , AccountManager accountManage
            , SourceManager sourceManager
            , ScheduleManager scheduleManager
            , PayMethodManager payMethodManager
            , TicketPriceManager ticketPriceManager
            , ActivityManager activityManager
            , CustomerManager customerManager
            , TravelAgencyManager travelManager
            ) :base(sourceManager, scheduleManager, payMethodManager, cacheManager, ticketPriceManager, customerManager, userManager, travelManager)
        {
            _tenantCache = tenantCache;
            _cacheManager = cacheManager;
            _impersonationManager = impersonationManager;
            _userLinkManager = userLinkManager;
            _identityOptions = identityOptions.Value;
            _dataFileObjectManager = dataFileObjectManager;
            _dataTempFileCacheManager = dataTempFileCacheManager;
            _accountManager = accountManage;
            _activityManager = activityManager;
        }
        /// <summary>
        /// 结账
        /// </summary>
        /// <param name="activitys">订单Id集合</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActivityResultModel> SettleAccount(List<Guid> activitys)
        {
            ActivityResultModel activityResult = new ActivityResultModel()
            {
                ResultCode = "000",
                ResultMessage = "结账成功"
            };
            try
            {
                //判断提交数据的正确性
                var list = this.IsGetActivity(activitys,false);
                //结账
                _accountManager.SettleAccount(list,(long)AbpSession.UserId);
            }
            catch (Exception ex)
            {
                return new ActivityResultModel()
                {
                    ResultCode = "001",
                    ResultMessage = "结账失败",
                    Detail = ex.Message + ex.StackTrace,
                };
            }
            return activityResult;
        }
        /// <summary>
        /// 取消结账
        /// </summary>
        /// <param name="activitys">订单Id集合</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActivityResultModel> RSettleAccount(List<Guid> accounts)
        {
            ActivityResultModel activityResult = new ActivityResultModel()
            {
                ResultCode = "000",
                ResultMessage = "取消结账成功"
            };
            try
            {
                //判断提交数据的正确性
                var list = this.IsGetAccount(accounts, AccountStatusEnum.NotAccount);
                //结账
                _accountManager.RSettleAccount(list, (long)AbpSession.UserId);
            }
            catch (Exception ex)
            {
                return new ActivityResultModel()
                {
                    ResultCode = "001",
                    ResultMessage = "取消结账失败",
                    Detail = ex.Message + ex.StackTrace,
                };
            }
            return activityResult;
        }
        /// <summary>
        /// 收款
        /// </summary>
        /// <param name="accounts">账单Id集合</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActivityResultModel> CollectAccounts(List<Guid> accounts)
        {
            ActivityResultModel activityResult = new ActivityResultModel()
            {
                ResultCode = "000",
                ResultMessage = "收款成功"
            };
            try
            {
                //判断提交数据的正确性
                var list = this.IsGetAccount(accounts, AccountStatusEnum.NotAccount);
                //结账
                _accountManager.CollectAccounts(list, (long)AbpSession.UserId);
            }
            catch (Exception ex)
            {
                return new ActivityResultModel()
                {
                    ResultCode = "001",
                    ResultMessage = "收款失败",
                    Detail = ex.Message + ex.StackTrace,
                };
            }
            return activityResult;
        }
        /// <summary>
        /// 取消收款
        /// </summary>
        /// <param name="accounts">账单Id集合</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActivityResultModel> RCollectAccounts(List<Guid> accounts)
        {
            ActivityResultModel activityResult = new ActivityResultModel()
            {
                ResultCode = "000",
                ResultMessage = "取消收款成功"
            };
            try
            {
                //判断提交数据的正确性
                var list = this.IsGetAccount(accounts, AccountStatusEnum.IsAccount);
                //结账
                _accountManager.RCollectAccounts(list, (long)AbpSession.UserId);
            }
            catch (Exception ex)
            {
                return new ActivityResultModel()
                {
                    ResultCode = "001",
                    ResultMessage = "取消收款失败",
                    Detail = ex.Message + ex.StackTrace,
                };
            }
            return activityResult;
        }
        #region 私有方法
        /// <summary>
        /// 判断结账数据是否有异常
        /// </summary>
        /// <returns></returns>
        private List<Activity> IsGetActivity(List<Guid> activitys,bool Closed)
        {
            //var idString = activitys.Select(m => m.Id).ToArray();
            var idString = activitys.ToArray();
            //查询所有订单
            var list = _activityManager.GetActivityListByIds(idString);
            if (list.Count != activitys.Count)
                throw new Exception("数据异常");
            if (list.Where(m => m.Closed == Closed).ToList().Count < activitys.Count)
                throw new Exception("存在" + (!Closed ? "已" : "未") + "结账订单");
            return list;
        }

        /// <summary>
        /// 判断收款数据是否有异常
        /// </summary>
        /// <returns></returns>
        private List<Account> IsGetAccount(List<Guid> accounts, AccountStatusEnum accountStatus)
        {
            //var idString = activitys.Select(m => m.Id).ToArray();
            var idString = accounts.ToArray();
            //查询所有订单
            var list = _accountManager.GetAccountListByIds(idString);
            if (list.Count != accounts.Count)
                throw new Exception("数据异常");
            if (list.Where(m => m.AccountStatus == accountStatus).ToList().Count < accounts.Count)
                throw new Exception("存在非" + CommonHelp.GetEnumDescription<AccountStatusEnum>(accountStatus) + "订单");
            return list;
        }
        /// <summary>
        /// 缓存中查询是否有剩余票
        /// </summary>
        /// <param name="ScheduleId">航班标识</param>
        /// <param name="TotalQuantity">购票数</param>
        private void IsExistenTicket(Schedule Schedule,int TotalQuantity)
        {
            if (Schedule.SurplusQuantity<TotalQuantity)
            {
                throw new UserFriendlyException("已无剩余票");
            }
            //重新设置剩余票数
            Schedule.SurplusQuantity -= TotalQuantity;
            TimeSpan slidingExpireTime = Schedule.EndTime - DateTime.Now;
            GetICache().SetAsync(Schedule.Id.ToString(), Schedule, slidingExpireTime);
        }

        #endregion
    }
}
